#pragma once

#include <functional>
#include <mutex>
#include <vector>
#include "channel.h"

class poll_poller;

class wakeuper final : public channel
{
    class EventFd
    {
      public:
        EventFd();
        ~EventFd();
        int fd() const
        {
            return event_fd_;
        }
        ssize_t read(uint64_t& flag);
        ssize_t write(uint64_t flag = 1);

      private:
#if defined(__CYGWIN__)
        int pipe_fd_[2];
#endif
        int event_fd_;
    };

  public:
    wakeuper(poll_poller* poller);
    ~wakeuper();

    void init();

    void run_in_loop(std::function<void()> func);

    void handle_read();
    void handle_write();

  private:
    void wakeup();

  private:
    bool                               call_funs_ = false;
    std::vector<std::function<void()>> pending_funcs_;
    EventFd                            wakeup_fd_;
};